package threadTest.myCompletableFuture;

import java.util.concurrent.*;

/**
 * 功能描述: 线程编排 任一完成即可, 如: 3个服务器都可以返回用户信息,哪一个快就用哪一个
 * 2024/08/09
 *
 * @author ZhangYi
 */
public class CompletableFutureAny {
	public static void main(String[] args) {
		ThreadPoolExecutor executor = new ThreadPoolExecutor(2, Runtime.getRuntime().availableProcessors(),
				0, TimeUnit.NANOSECONDS, new ArrayBlockingQueue<>(10), new ThreadPoolExecutor.CallerRunsPolicy());

		String userId = "00000";
		CompletableFuture<String> userInfoServer1CompletableFuture = CompletableFuture.supplyAsync(() -> {
			return new UserService().getUserInfoFromServe1(userId);
		}, executor);

		CompletableFuture<String> userInfoServer2CompletableFuture = CompletableFuture.supplyAsync(() -> {
			return new UserService().getUserInfoFromServer2(userId);
		}, executor);
		CompletableFuture<String> userInfoServer3CompletableFuture = CompletableFuture.supplyAsync(() -> {
			return new UserService().getUserInfoFromServer3(userId);
		}, executor);


		// 使用 anyOf 等待任意一个 CompletableFuture 完成
		CompletableFuture<Object> anyUserInfoFuture = CompletableFuture.anyOf(
				userInfoServer1CompletableFuture, userInfoServer2CompletableFuture, userInfoServer3CompletableFuture);

		try {
			System.out.println("获取到的用户信息为"+anyUserInfoFuture.get());

		} catch (InterruptedException e) {
			throw new RuntimeException(e);
		} catch (ExecutionException e) {
			throw new RuntimeException(e);
		}
		System.out.println("线程结束了");

		executor.shutdown();

		// 如果线程池是需要复用的,那么在jvm的运行期间,不显示的关闭,也是可以的
		try {
			if (!executor.awaitTermination(5, TimeUnit.SECONDS)) {
				executor.shutdownNow();
				if (!executor.awaitTermination(5, TimeUnit.SECONDS)){
					System.out.println("线程池关闭失败");
				}
			}
		} catch (InterruptedException e) {
			executor.shutdownNow();
			Thread.currentThread().interrupt();
		}
	}
}
